<template>
  <div class="screen-config-container">
    <div class="header-actions">
      <el-button type="primary" @click="handleRelation">建立关系</el-button>
      <el-button type="primary" @click="handleAdd">新增</el-button>
    </div>

    <div class="screen-config-content">
      <el-table
        :data="tableData"
        row-key="pkid"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        class="screen-config-table"
        ref="tableRef"
        @expand-change="handleExpandChange"
        :height="tableHeight"
      >
        <el-table-column prop="name" label="名称" width="400" />
        <el-table-column prop="url" label="url" />
        <el-table-column label="操作" width="150" fixed="right">
          <template #default="scope">
            <el-button type="text" @click="handleEdit(scope.row)"
              >编辑</el-button
            >
            <el-button type="text" style="color: red" @click="handleDelete(scope.row)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 新增编辑弹窗 -->
    <ConfigFormDialog
      :visible="dialogVisible"
      :form-data="formData"
      :parent-options="parentOptions"
      :submit-loading="submitLoading"
      @update:visible="dialogVisible = $event"
      @submit="handleFormSubmit"
      @close="handleDialogClose"
    />

    <!-- 建立关系弹窗 -->
    <RelationDialog
      ref="relationDialogRef"
      :visible="relationDialogVisible"
      :area-options="areaOptions"
      :config-tree-data="configTreeData"
      :submit-loading="relationSubmitLoading"
      @update:visible="relationDialogVisible = $event"
      @submit="handleRelationSubmit"
      @close="handleRelationDialogClose"
      @area-change="handleAreaChange"
    />
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, computed, nextTick } from 'vue'
// @ts-ignore
import Sortable from 'sortablejs'
import {
  getScreenConfigTree,
  addOrUpdateScreenConfig,
  deleteScreenConfig,
  moveScreenConfig,
  getAreaList,
  getAreaRelation,
  updateAreaRelation,
} from '@/api/screen-management/screen-config'
import { Message, MessageBox } from 'element-ui'
import ConfigFormDialog from './components/ConfigFormDialog.vue'
import RelationDialog from './components/RelationDialog.vue'

const ElMessage = Message
const ElMessageBox = MessageBox

interface TreeItem {
  pkid: string
  name: string
  url: string
  parentId: string
  children?: TreeItem[]
  hasChildren?: boolean
}

interface FormData {
  pkid: string
  name: string
  url: string
  parentId: string | null
}

interface AreaItem {
  pkid: string
  areaName: string
  areaCode: string
  parentCode: string
  level: number
  children?: AreaItem[]
}

interface RelationFormData {
  areaId: string
  serviceIds: string[]
}

const tableRef = ref()
const relationDialogRef = ref()
const tableData = ref<TreeItem[]>([])
const parentOptions = ref<TreeItem[]>([])
const dialogVisible = ref(false)
const submitLoading = ref(false)
const relationDialogVisible = ref(false)
const areaOptions = ref<AreaItem[]>([])
const configTreeData = ref<TreeItem[]>([])
const relationSubmitLoading = ref(false)
const expandedRowKeys = ref<Set<string>>(new Set())

const tableHeight = computed(() => {
  return window.innerHeight - 250
})

const formData = ref<FormData>({
  pkid: '',
  name: '',
  url: '',
  parentId: '',
})

let sortableInstance: Sortable | null = null

const fetchTreeData = async () => {
  try {
    const res: any = await getScreenConfigTree()
    parentOptions.value = res.data || []
    tableData.value = []
    await nextTick()
    tableData.value = res.data || []

    await nextTick()

    if (tableRef.value) {
      tableRef.value.doLayout()
    }

    expandedRowKeys.value.clear()
    
    initSortable()
  } catch (error) {
    console.error('Failed to fetch tree data:', error)
    ElMessage.error('获取数据失败')
  }
}

const initSortable = () => {
  if (sortableInstance) {
    sortableInstance.destroy()
    sortableInstance = null
  }

  const el = tableRef.value?.$el?.querySelector('.el-table__body-wrapper tbody')
  if (!el) return

  let flatData: TreeItem[] = []

  sortableInstance = Sortable.create(el, {
    animation: 150,
    ghostClass: 'sortable-ghost',
    onStart: () => {
      flatData = []
      const flatten = (items: TreeItem[]) => {
        items.forEach((item) => {
          flatData.push(item)
          if (item.children && item.children.length > 0) {
            flatten(item.children)
          }
        })
      }
      flatten(tableData.value)
    },
    onEnd: async (evt: any) => {
      const { oldIndex, newIndex } = evt
      if (
        oldIndex === undefined ||
        newIndex === undefined ||
        oldIndex === newIndex
      )
        return

      const movedItem = flatData[oldIndex]
      if (!movedItem) return

      try {
        // 计算 frontId：需要考虑层级关系，只在同一层级内计算前一个元素
        const frontId = calculateFrontId(movedItem, oldIndex, newIndex, flatData)
        
        const res: any = await moveScreenConfig({
          currentId: movedItem.pkid,
          frontId: frontId,
        })
        if (res.success) {
          ElMessage.success('排序成功')
          // 重新获取数据以确保数据一致性，但保持展开状态
          const expandedKeys = Array.from(expandedRowKeys.value)
          await fetchTreeData()
          // 恢复展开状态
          await nextTick()
          restoreExpandedState(expandedKeys)
        } else {
          ElMessage.error(res.message)
          await fetchTreeData()
        }
      } catch (error) {
        console.error('Failed to move item:', error)
        ElMessage.error('排序失败')
        await fetchTreeData()
      }
    },
  })
}

const handleExpandChange = (row: TreeItem, expanded: boolean) => {
  if (expanded) {
    expandedRowKeys.value.add(row.pkid)
  } else {
    expandedRowKeys.value.delete(row.pkid)
  }
}

// 恢复展开状态
const restoreExpandedState = async (expandedKeys: string[]) => {
  if (!tableRef.value || !expandedKeys.length) return
  
  // 等待表格完全渲染
  await nextTick()
  await new Promise(resolve => setTimeout(resolve, 100))
  
  // 找到需要展开的行并展开
  const findAndExpandRows = (items: TreeItem[]) => {
    items.forEach((item) => {
      if (expandedKeys.includes(item.pkid)) {
        setTimeout(() => {
          try {
            tableRef.value.toggleRowExpansion(item, true)
            expandedRowKeys.value.add(item.pkid)
          } catch (error) {
            console.log('Failed to expand row:', item.name, error)
          }
        }, 50)
      }
      if (item.children && item.children.length > 0) {
        findAndExpandRows(item.children)
      }
    })
  }
  
  findAndExpandRows(tableData.value)
}

// 计算 frontId，考虑层级关系
const calculateFrontId = (movedItem: TreeItem, oldIndex: number, newIndex: number, flatData: TreeItem[]): string => {
  const movedParentId = movedItem.parentId
  
  // 获取拖拽后的目标位置元素
  const targetItem = flatData[newIndex]
  if (!targetItem) return '-1'
  
  // 如果目标位置的元素与移动元素不在同一层级，说明是跨层级拖拽
  // 这种情况下，需要找到目标层级中，目标位置前面的同层级元素
  const targetParentId = targetItem.parentId
  
  // 从目标位置向前查找，找到第一个与目标元素同层级的元素
  for (let i = newIndex - 1; i >= 0; i--) {
    const item = flatData[i]
    if (item && item.parentId === targetParentId && item.pkid !== movedItem.pkid) {
      return item.pkid
    }
  }
  
  // 如果没有找到，说明拖到了目标层级的第一个位置
  return '-1'
}





const handleRelation = async () => {
  try {
    const areaRes: any = await getAreaList()
    if (areaRes.success && areaRes.data && areaRes.data.length > 0) {
      areaOptions.value = areaRes.data[0].children || []
    }

    const configRes: any = await getScreenConfigTree()
    if (configRes.success) {
      configTreeData.value = configRes.data || []
    }

    relationDialogRef.value?.resetForm()
    
    relationDialogVisible.value = true
  } catch (error) {
    console.error('Failed to load relation data:', error)
    ElMessage.error('加载数据失败')
  }
}

const handleAreaChange = async (areaId: string) => {
  if (!areaId) {
    relationDialogRef.value?.clearRelationData()
    return
  }

  try {
    const res: any = await getAreaRelation(areaId)
    if (res.success && res.data) {
      relationDialogRef.value?.setRelationData(res.data || [])
    } else {
      relationDialogRef.value?.clearRelationData()
    }
  } catch (error) {
    console.error('Failed to get area relation:', error)
    relationDialogRef.value?.clearRelationData()
  }
}

const handleRelationSubmit = async (relationData: RelationFormData) => {
  try {
    relationSubmitLoading.value = true

    const submitData = [
      {
        areaId: relationData.areaId,
        serviceIds: relationData.serviceIds,
      },
    ]

    const res: any = await updateAreaRelation(submitData)
    if (res.success) {
      ElMessage.success('建立关系成功')
      relationDialogVisible.value = false
    } else {
      ElMessage.error(res.message || '建立关系失败')
    }
  } catch (error) {
    console.error('Failed to update relation:', error)
    ElMessage.error('建立关系失败')
  } finally {
    relationSubmitLoading.value = false
  }
}

const handleRelationDialogClose = () => {
}

const handleAdd = () => {
  formData.value = {
    pkid: '',
    name: '',
    parentId: '',
    url: '',
  }
  dialogVisible.value = true
}

const handleEdit = (row: TreeItem) => {
  formData.value = {
    pkid: row.pkid,
    name: row.name,
    parentId: row.parentId === '-1' ? null : row.parentId,
    url: row.url,
  }
  dialogVisible.value = true
}

const handleDelete = async (row: TreeItem) => {
  try {
    await ElMessageBox.confirm(`确定要删除${row.name}吗？`, '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })

    const res: any = await deleteScreenConfig({ pkid: row.pkid })
    if (res.success) {
      ElMessage.success('删除成功')
      fetchTreeData()
    } else {
      ElMessage.error(res.message)
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('Delete failed:', error)
      ElMessage.error('删除失败')
    }
  }
}

const handleFormSubmit = async (submitData: FormData) => {
  try {
    submitLoading.value = true
    await addOrUpdateScreenConfig(submitData)
    ElMessage.success(submitData.pkid ? '编辑成功' : '新增成功')
    dialogVisible.value = false
    fetchTreeData()
  } catch (error) {
    console.error('Failed to submit:', error)
    ElMessage.error('操作失败')
  } finally {
    submitLoading.value = false
  }
}

const handleDialogClose = () => {

}

onMounted(() => {
  fetchTreeData()
})
</script>

<style scoped lang="scss">
.screen-config-container {
  width: 100%;
  height: calc(100% - 27px);
  background-color: white;
  box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.1);
  border-radius: 2px;
  display: flex;
  flex-direction: column;

  .header-actions {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 20px;
    gap: 10px;
    padding: 20px;
    border-bottom: 1px solid #eeeff5;
    flex-shrink: 0;
  }

  .screen-config-content {
    margin: 0 18px;
    flex: 1;
    overflow: hidden;
  }

  .screen-config-table {
    width: 100%;

    :deep(.sortable-ghost) {
      opacity: 0.5;
      background-color: #f0f9ff;
    }
  }


}
</style>

